package com.loren.demo27.annotation;

import lombok.AllArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.Set;

@Aspect
@Component
@AllArgsConstructor
public class ParamCheckedAspect {

    private final Validator validator;

    @Before("execution(* com.loren.demo27..*(..))")
    public void doBefore(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Parameter[] parameters = signature.getMethod().getParameters();
        for (Parameter parameter : parameters) {
            // 如果没有被注解修饰，直接跳过
            ParamChecked paramChecked = parameter.getAnnotation(ParamChecked.class);
            if (paramChecked == null) {
                continue;
            }
            // 查找目标参数 - 不会有为空的情况
            Object object = Arrays.stream(joinPoint.getArgs())
                    .filter(arg -> parameter.getType().isAssignableFrom(arg.getClass()))
                    .findFirst()
                    .orElse(null);
            Set<ConstraintViolation<Object>> violations = this.validator.validate(object);
            if (!violations.isEmpty()) {
                for (ConstraintViolation<Object> violation : violations) {
                    System.out.println(violation);
                }
            }
        }
    }

}
